<?php

namespace App\Library;

use App\Models\video\CourseModel;
use App\Models\video\LevelModel;
use App\Models\video\OrderModel;
use App\Models\video\VideoUserModel;
use App\Models\video\VodVideoModel;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;

class WxNotify
{
    /*
     * 服务器点对点
     * 该方法不能判断其它的，比如登录状态，不然会跳到其它地方，导致不能改变订单信息
     */
    public function handleNotify()
    {
        $post_data = $_REQUEST;
        if($post_data==null){
            $post_data = file_get_contents("php://input");
        }
        if($post_data == null){
            $post_data = $GLOBALS['HTTP_RAW_POST_DATA'];
        }
        $data = $this->fromXml($post_data);
        if ($data['result_code'] != 'SUCCESS' || $data['return_code'] != 'SUCCESS') {
            $result = array(
                'return_code' => 'FAIL',
                'return_msg' => empty($data['return_msg']) ? $data['err_code_des'] : $data['return_msg']
            );
            return $this->toXml($result);
        }
        if (!array_key_exists("transaction_id", $data)) {
            $result = array(
                'return_code' => 'FAIL',
                'return_msg' => "transaction_id参数不存在"
            );
            return $this->toXml($result);
        }
        $result = array('return_code' => 'SUCCESS', 'return_msg' => "OK");
        if(empty($data["attach"])){
            $recordData = DB::table("new_work_pay_record")->where("order_sn", $data['out_trade_no'])
                ->select("status", "id")->first();
            if(!empty($recordData->id) && $recordData->status == "0"){
                $res = DB::table("new_work_pay_record")->where("id", $recordData->id)->update([
                    "status" => "1", "trade_no" => $data["transaction_id"]
                ]);
                if(!$res) {
                    $result = array('return_code' => 'FAIL', 'return_msg' => "");
                }
            }
        }else{
            $attach = json_decode($data["attach"], true); // type 1:视频，2：课程，3：会员
            $orderData = OrderModel::getFields("id,belong_id,status,user_id", ["id" => $attach["orderId"]], true, false);
            if(empty($orderData)){
                $result = array('return_code' => 'FAIL', 'return_msg' => "");
                return $this->toXml($result);
            }
            if($orderData["status"] != '1'){
                $result = array('return_code' => 'FAIL', 'return_msg' => "");
                return $this->toXml($result);
            }
            $info = null;
            if ($attach["type"] == '3') { // 购买会员
                $levelData = LevelModel::getFields("name,use_day", ["id" => $orderData["belongId"]], true, false);
                $levelData["id"] = $orderData["belongId"];
                $info = json_encode($levelData, JSON_UNESCAPED_UNICODE);
            }elseif($attach["type"] == '1'){ // 视频
                $videoData = VodVideoModel::getFields("broadcaster_id,title,vid,cover_img_id", ["id" => $orderData["belongId"]]);
                $videoData["id"] = $orderData["belongId"];
                $info = json_encode($videoData, JSON_UNESCAPED_UNICODE);
            }elseif($attach["type"] == '2'){ // 课程
                $courseData = CourseModel::getFields("broadcaster_id,name,cover_img_id", ["id" => $orderData["belongId"]]);
                $courseData["id"] = $orderData["belongId"];
                $info = json_encode($courseData, JSON_UNESCAPED_UNICODE);
            }
            if(OrderModel::doUpdate(["status" => 2, "trade_no" => $data["transaction_id"], "openid" => $data["openid"], "pay_time" => Carbon::now(), "info" => $info], ["id" => $attach["orderId"]])) {
                if ($attach["type"] == '3' && !empty($levelData)) { // 购买会员
                    $userData = VideoUserModel::getFields("level_time", ["id" => $orderData["userId"]], true, false);
                    $levelTime = ($userData["levelTime"] && $userData["levelTime"] > time() ? $userData["levelTime"] : time()) + ($levelData["useDay"] * 86400);
                    VideoUserModel::doUpdate(["level_id" => $orderData["belongId"], "level_time" => $levelTime], ["id" => $orderData["userId"]]);
                }
            }
        }
        return $this->toXml($result);
    }

    /**
     * @param $xml
     * @return mixed
     * @throws Exception
     * 将xml转为array
     */
    public function fromXml($xml)
    {
        if(!$xml){
            Log::write("支付回调解析xml：xml数据异常或者为空");
            return false;
        }
        //将XML转为array
        //禁止引用外部xml实体
        libxml_disable_entity_loader(true);
        $values = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
        return $values;
    }

    /**
     * 输出xml字符
     **/
    public function toXml($values)
    {
        if(!is_array($values)
            || count($values) <= 0)
        {
            return false;
        }

        $xml = "<xml>";
        foreach ($values as $key=>$val)
        {
            if (is_numeric($val)){
                $xml.="<".$key.">".$val."</".$key.">";
            }else{
                $xml.="<".$key."><![CDATA[".$val."]]></".$key.">";
            }
        }
        $xml.="</xml>";
        return $xml;
    }
}